package com.liuqing.www.xml解析;

import java.io.File;
import java.net.URLDecoder;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * dom解析效率低，占内存，读取时常驻内存，用于常常读取一个文件，好处在于面向多编程语言是w3c标准之一
 * 基本10M文件就溢出
 * 故如javascript就用dom来解析实现跨语言
 * 素(Element)和结点(Node)的区别，元素是一个小范围的定义，必须是含有完整信息的结点才是一个元素，
 * 例如<bh/>。但是一个结点不一定是一个元素，而一个元素一定是一个结点。
 * node有几个子类型：

    Element, Element.ELEMENT_NODE  1   惟一一个有属性，

      Text,                        3

    Attribute,                    2

  RootElement, 

    Comment,                       8  8

    Namespace等
Element是可以有属性和子节点的node
Element是从Node继承的

//转换

if (node.getNodeType() == Element.ELEMENT_NODE) 

{
     Element e = (Element) node; 

}


 * @author 韩世超
 *
 */
public class DOM解析 {
	/**
	 * @param args
	 */
	private static Document doc;
	private static String path;
	public static void main(String[] args) {
		getDoc("/com/liuqing/www/xml解析/resourse/student.xml");
		addNode("003","李四","女");
		modifyStudent("003","李四44");
		ReadXML();
		writeFile();
	}
	static void writeFile(){
		DocumentBuilderFactory Factory=DocumentBuilderFactory.newInstance();
		DocumentBuilder db;
		try{
			db = Factory.newDocumentBuilder();
			doc= db.newDocument();
			Element e=doc.createElement("students");
			Element e2=doc.createElement("student");
			e2.setTextContent("李黎");
			e.setAttribute("id", "001");
			e.appendChild(e2);
			doc.appendChild(e);
			  Transformer tfer=	TransformerFactory.newInstance().newTransformer();
			  DOMSource dsource = new DOMSource(doc); 
//			     tfer.setOutputProperty(OutputKeys.ENCODING, "GB2312");
//			        tfer.setOutputProperty(OutputKeys.INDENT, "yes");
			  StreamResult sr = new StreamResult(new File("e:/students.xml")); 
			  tfer.transform(dsource, sr); 
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 根据dom保存dom
	 */
	static void SaveFile(){
		TransformerFactory tf = TransformerFactory.newInstance(); 
	    Transformer tfer;
		try {
			tfer = tf.newTransformer();
			 DOMSource dsource = new DOMSource(doc); 
			//tfer.setOutputProperty(OutputKeys.ENCODING, "GB2312");
			    StreamResult sr = new StreamResult(new File("e:/student.xml")); 
			    tfer.transform(dsource, sr); 
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	   

	}
	/**
	 * 获取根据path获取doc，包含如何获取工程中文件目录的方法
	 * @param filepath
	 */
	static void getDoc(String filepath){
		try {
		path=URLDecoder.decode(DOM解析.class.getResource(filepath).getFile(),"utf-8");
		File f=new File(path);
		DocumentBuilderFactory Factory=DocumentBuilderFactory.newInstance();
		DocumentBuilder db;
			db = Factory.newDocumentBuilder();
			doc= db.parse(f);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/*
	 * 修改dom
	 */
	public static void  modifyStudent(String id,String name){
		NodeList li=doc.getElementsByTagName("name");
		for(int i=0;i<li.getLength();i++){
			Node di=li.item(i);
			if(di.getNodeType()!=1){
				continue;
			}
			Node father=di.getParentNode();//《比如 id="id"》
			if(father.getAttributes().getNamedItem("id").getNodeValue().equals(id)){
				di.setTextContent(name);//<name>xx</name>修改xx
				return ;
			}
		}
	}
	static void addNode(String id,String name,String sex){
		Element newele=doc.createElement("student");
		newele.setAttribute("id", "003");
		Element nameel=doc.createElement("name");
		nameel.setTextContent(name);
		Element sexel=doc.createElement("sex");
		sexel.setTextContent(sex);
		newele.appendChild(nameel);
		newele.appendChild(sexel);
		doc.getDocumentElement().appendChild(newele);
	}
	static void  ReadXML(){
		Element root=doc.getDocumentElement();
		System.out.println(root.getNodeName());
		NodeList rootlist=root.getChildNodes();
		for(int i=0;i<rootlist.getLength();i++){
			Node n1=rootlist.item(i);
			if( n1.getNodeType()!=1){
				continue;
			}
			System.out.println("   "+n1.getNodeName());
			if(n1.getAttributes()!=null){
				System.out.println(n1.getAttributes().item(0).getNodeName()+":"+n1.getAttributes().item(0).getNodeValue());
			}
			for(int j=0;j<n1.getChildNodes().getLength();j++){
				Node n2=n1.getChildNodes().item(j);
				if( n2.getNodeType()!=1){
					continue;
				}
				System.out.print("    "+n2.getNodeName()+":");
//				if(n1.getAttributes()!=null){
//					System.out.println(n2.getAttributes().item(0).getNodeName()+":"+n1.getAttributes().item(0).getNodeValue());
//				}
				System.out.println(n2.getTextContent());
			}
		}
	}
}
